import { Component, OnInit, AfterViewInit, AfterViewChecked, ElementRef, ViewChild, Injector, Input, Output, EventEmitter } from '@angular/core';
// import { AppComponentBase } from '@shared/common/app-component-base';
import { AppComponentBase } from '@shared/app-component-base';

import { GetUserPermissionsForEditOutput } from '@shared/service-proxies/service-proxies';
import { PermissionTreeEditModel } from './permission-tree-edit.model';

import * as _ from 'lodash';

@Component({
    selector: 'permission-tree',
    template:
    `<nz-tree [nzNodes]="nodes"
    [nzCheckable]="true"
    [nzShowLine]="true"
    (nzEvent)="onEvent($event)"
    (nzCheck)="onCheck($event)"></nz-tree>`
})
export class PermissionTreeComponent extends AppComponentBase implements OnInit, AfterViewInit, AfterViewChecked {

    nodes = [];

    treeData= [];
    
    set editData(val: PermissionTreeEditModel) {
        this._editData = val;
        this.refreshTree();
    }

    private _editData: PermissionTreeEditModel;

    constructor(private _element: ElementRef,
        injector: Injector
    ) {
        super(injector);
    }

    ngOnInit(): void {
    }

    onEvent(event): void {
        console.log(event,'onEvent');
    }

    ngAfterViewInit(): void {
      //  this._$tree = $(this._element.nativeElement);

        // this.refreshTree();
    }

    ngAfterViewChecked(): void {

    }

    getGrantedPermissionNames(): string[] {

        /*
        if (!this._$tree || !this._createdTreeBefore) {
            return [];
        }
*/
        
        let permissionNames = [];
       
        permissionNames = _.map( _.filter(this.treeData, item => {
            return item.checked || item.halfChecked ;
        }), item => {
            return item.id;
        });

        return permissionNames;
    }

    refreshTree(): void {

        const self = this;

        this.treeData = _.map(this._editData.permissions, function (item) {
            return {
                id: item.name,
                parent: item.parentName ? item.parentName : '#',
                name: item.displayName,
                disableCheckbox: false,
                checked: _.includes(self._editData.grantedPermissionNames, item.name)
            };
        });

        this.nodes = this.createNode('#', this.treeData);

        /*
        let self = this;

        if (this._createdTreeBefore) {
            this._$tree.jstree('destroy');
        }

        this._createdTreeBefore = false;

        if (!this._editData || !this._$tree) {
            return;
        }

        

        this._$tree.jstree({
            'core': {
                data: treeData
            },
            'types': {
                'default': {
                    'icon': 'fa fa-folder m--font-warning'
                },
                'file': {
                    'icon': 'fa fa-file m--font-warning'
                }
            },
            'checkbox': {
                keep_selected_style: false,
                three_state: false,
                cascade: ''
            },
            plugins: ['checkbox', 'types']
        });

        this._createdTreeBefore = true;

        let inTreeChangeEvent = false;

        function selectNodeAndAllParents(node) {
            self._$tree.jstree('select_node', node, true);
            let parent = self._$tree.jstree('get_parent', node);
            if (parent) {
                selectNodeAndAllParents(parent);
            }
        }

        this._$tree.on('changed.jstree', function (e, data) {
            if (!data.node) {
                return;
            }

            let wasInTreeChangeEvent = inTreeChangeEvent;
            if (!wasInTreeChangeEvent) {
                inTreeChangeEvent = true;
            }

            let childrenNodes;

            if (data.node.state.selected) {
                selectNodeAndAllParents(self._$tree.jstree('get_parent', data.node));

                childrenNodes = $.makeArray(self._$tree.jstree('get_children_dom', data.node));
                self._$tree.jstree('select_node', childrenNodes);

            } else {
                childrenNodes = $.makeArray(self._$tree.jstree('get_children_dom', data.node));
                self._$tree.jstree('deselect_node', childrenNodes);
            }

            if (!wasInTreeChangeEvent) {
                inTreeChangeEvent = false;
            
        });
        }*/
    }

    

    createNode(parent, source) {
        const fs = _.filter(source, item => {
            return item.parent === parent ;
        });

        _.forEach(fs, item => {
            
              item.children = this.createNode(item.id, source);
            
        });

        return fs;

    }

    inTreeChangeEvent = false;

    onCheck($event){
        
        let wasInTreeChangeEvent = this.inTreeChangeEvent;
        if (!wasInTreeChangeEvent) {
            this.inTreeChangeEvent = true;
        }


        let childrenNodes;

        if($event.checked){
            this.selectNodeAndAllParents($event.node);
        }
        else{
            // 如果是子未选中，不影响父节点的状态
            this.deSelectNodeAndAllParents($event.node);
        }

        if (!wasInTreeChangeEvent) {
            this.inTreeChangeEvent = false;
        }

    }

    selectNodeAndAllParents(node) {
        let parent = node.parent;
        
        if (parent) {
            this.selectNodeAndAllParents(parent);
        }
    }

    deSelectNodeAndAllParents(node) {
        let parent = node.parent;
        if (parent) {
            // 保证父节点不受子节点取消而取消
            parent.data.checked=true;
            parent.data.halfChecked=false;
            this.deSelectNodeAndAllParents(parent);
        }
    }




}
